package org.mics.cyy.backUser.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.mics.core.page.PageInfo;
import org.mics.core.page.PageQuery;
import org.mics.core.response.PageDataResponse;
import org.mics.cyy.backUser.entity.MenuDO;
import org.mics.cyy.backUser.entity.RoleMenuDO;
import org.mics.cyy.backUser.repository.MenuRepository;
import org.mics.cyy.backUser.repository.RoleMenuRepository;
import org.mics.cyy.backUser.request.MenuRequest;
import org.mics.cyy.backUser.service.MenuService;
import org.mics.cyy.backUser.vo.MenuVO;
import org.mics.lang.bean.BeanConvertUtil;
import org.mics.lang.exception.CustomException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

/**
 * 菜单服务实现
 * @author mics
 * @date 2023-10-9
 * @version  1.0
 */
@Service
public class MenuServiceImpl implements MenuService{
	@Resource
	private MenuRepository menuRepository;
	@Resource
	private RoleMenuRepository roleMenuRepository;
	
	@Override
	@Transactional
	public String add(MenuRequest menuRequest) {
		MenuDO menuDO  = BeanConvertUtil.convert(menuRequest, MenuDO.class);
		menuRepository.save(menuDO);
		return menuDO.getId();
	}

	@Override
	@Transactional
	public void delete(String id) {
		//判断是否有子菜单
		int count = menuRepository.countByParentId(id);
		if(count > 0) {
			throw new CustomException("存在下级子菜单不能删除，请先删除下级菜单");
		}
		//删除角色菜单关系
		List<RoleMenuDO> roleMenuDOs = roleMenuRepository.findByMenuId(id);
		roleMenuRepository.deleteAll(roleMenuDOs);
		//删除菜单
		menuRepository.deleteById(id);
	}

	@Override
	public PageDataResponse<MenuVO> listByPage(PageQuery pageQuery) {
		//规格定义
        Specification<MenuDO> specification = new Specification<MenuDO>() {
			private static final long serialVersionUID = -8785309034575411806L;
			/**
             * 构造断言
             * @param root 实体对象引用
             * @param query 规则查询对象
             * @param cb 规则构建对象
             * @return 断言
             */
            @Override
            public Predicate toPredicate(Root<MenuDO> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            	List<Predicate> lstPredicates = new ArrayList<  >();
				Predicate[] arrayPredicates = new Predicate[lstPredicates.size()];
				if(StringUtils.isNotBlank(pageQuery.getKey())) {
					lstPredicates.add(cb.like(root.get("name").as(String.class),"%"+pageQuery.getKey()+"%"));
				}
				return cb.and(lstPredicates.toArray(arrayPredicates));
            }
        };
        Pageable pageable = PageRequest.of(pageQuery.getPageIndex()-1>0?pageQuery.getPageIndex():0,pageQuery.getPageSize(), Sort.Direction.DESC, "createDate");
        //查询
       Page<MenuDO> page = this.menuRepository.findAll(specification,pageable);
       PageInfo pageInfo = new PageInfo();
       pageInfo.setPageNo(page.getNumber());
       pageInfo.setPageSize(page.getSize());
       pageInfo.setTotalCount(page.getTotalElements());
       pageInfo.setTotalPage(page.getTotalPages());
       List<MenuVO> pageList = BeanConvertUtil.convertList(page.getContent(), MenuVO.class);
      return new PageDataResponse<>(pageInfo,pageList);
	}

	@Override
	public List<MenuDO> findByRoleId(String roleId) {
		List<RoleMenuDO> roleMenuDOs = roleMenuRepository.findByRoleId(roleId);
		List<String> ids = new ArrayList<String>();
		roleMenuDOs.forEach(v->{
			ids.add(v.getMenuId());
		});
		List<MenuDO> menuDOs =  menuRepository.findByIdIn(ids);
		return menuDOs;
	}

	@Override
	public List<MenuDO> findByParentId(String parentId) {
		return menuRepository.findByParentId(parentId);
	}

	@Override
	public List<MenuDO> list(String name) {
		if(StringUtils.isNotBlank(name)) {
			return menuRepository.findByNameLike("%"+name+"%");
		}else {
			return menuRepository.findAll();
		}
	}
}
